﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Threading;
using Threading = System.Threading;
using Microsoft.Forums.OfflineStore;
using System.IO;
using System.Data.SqlServerCe;
using System.Diagnostics;

namespace Microsoft.Forums.ForumsClient.Models
{
    /// <summary>
    /// A post model container which models them in a hierarchy
    /// </summary>
    public abstract class HierarchicalPostContainerModel : BindableObject, IPostModelContainer<ThreadedPostViewModel>
    {

        private Dispatcher dispatcherUI;

        /// <summary>
        /// Has the rootPosts been loaded yet?
        /// </summary>
        bool areRootPostsLoaded;

        /// <summary>
        /// The select post model
        /// </summary>
        ThreadedPostViewModel selectedPostModel;

        protected DispatchingObservableCollection<ThreadedPostViewModel> rootPosts;
        protected object rootPostsLock = new object();

        /// <summary>
        /// The collection of root posts
        /// </summary>
        public DispatchingObservableCollection<ThreadedPostViewModel> Posts
        {
            get
            {
                if (rootPosts == null)
                {
                    lock (rootPostsLock)
                    {

                        if (rootPosts == null)
                        {
                            rootPosts = new DispatchingObservableCollection<ThreadedPostViewModel>();
                            PopulateRootPosts();
                        }
                    }
                }
                return rootPosts;
            }
            private set
            {
                rootPosts = value;
            }
        }


        /// <summary>
        /// Gets or sets the dispatcher UI.
        /// </summary>
        /// <value>The dispatcher UI.</value>
        protected Dispatcher DispatcherUI
        {
            get
            {
                return dispatcherUI;
            }
            set
            {
                dispatcherUI = value;
            }
        }

        /// <summary>
        ///  Get / Set whether or not this Forum has had its rootPosts loaded yet
        /// </summary>
        public bool AreRootPostsLoaded
        {
            get
            {
                return areRootPostsLoaded;
            }
            set
            {

                areRootPostsLoaded = value;
                OnPropertyChanged("AreRootPostsLoaded");
            }
        }


        /// <summary>
        /// Gets or sets the selected post model.
        /// </summary>
        /// <value>The selected post model.</value>
        public ThreadedPostViewModel SelectedPostModel
        {
            get
            {
                return selectedPostModel;
            }
            set
            {
                if (selectedPostModel != value)
                {
                    selectedPostModel = value;
                    OnPropertyChanged("SelectedPostModel");
                }
            }
        }



        protected HierarchicalPostContainerModel(Dispatcher dispatcher)
        {
            if (dispatcher == null) throw new ArgumentNullException("dispatcher", "dispatcher must not be null");
            dispatcherUI = dispatcher;
        }


        /// <summary>
        /// Gets the root posts.
        /// </summary>
        /// <param name="store">The store.</param>
        /// <returns></returns>
        protected abstract IEnumerable<Post> GetRootPosts(ForumsOfflineStore store);


        /// <summary>
        /// Populate the root posts
        /// </summary>
        protected void PopulateRootPosts()
        {
            if (rootPosts == null) return;
            rootPosts.Clear();
            Threading.ThreadPool.QueueUserWorkItem(
                     delegate
                     {
                         using (var store = AppDataModel.Instance.ReadOnlyDataContext)
                         {
                             var posts = GetRootPosts(store);
                             if (posts != null)
                             {
                                 try
                                 {
                                     foreach (var p in posts)
                                     {

                                         var storedPost = ObjectRegistry.GetPost(p);
                                         var pc = new ThreadedPostViewModel(storedPost, dispatcherUI);

                                         Thread thread = ObjectRegistry.GetThread(storedPost.ForumId, p.ThreadId);
                                         pc.ThreadIfRootPost = thread;
                                         Posts.Add(pc);
                                     }
                                 }
                                 catch (SqlCeException e)
                                 {
                                     Debug.WriteLine("Query cannot complete, possible cause is the data has been cleared from the database");
                                     Debug.WriteLine(e);
                                 }

                             }

                         }

                         // Indicate that the root posts have been loaded
                         AreRootPostsLoaded = true;

                     });
        }



    }
}
